package czk.jvm.lecture.alibaba;

/**
 * 什么是DCL失效问题？
 *
 * 假如线程A执行到instance = new SingletonKerriganD()，大致做了如下三件事：
 *
 *     1 给实例分配内存
 *     2 调用构造函数，初始化成员字段
 *     3 将instance 对象指向分配的内存空间（此时sInstance不是null）
 *
 * 如果执行顺序是1-3-2，那多线程下，A线程先执行3，2还没执行的时候，此时instance！=null，
 * 这时候，B线程直接取走instance ，使用会出错，难以追踪。JDK1.5及之后的volatile 解决了DCL失效问题（双重锁定失效）
 */
public class Singleton {
    //这里加volatitle是为了避免DCL失效
    private volatile static Singleton singleton=null;
    //私有构造
    private Singleton(){}

    /**
     *  DCL对instance进行了两次null判断
     *  第一层判断主要是为了避免不必要的同步
     * 第二层的判断则是为了在null的情况下创建实例。
     * @return
     */
    public static Singleton getInstance(){
        if (singleton==null){
            synchronized (Singleton.class){
                singleton=new Singleton();
            }
        }
        return singleton;
    }
}
